<template>
  <!-- 容器 div，定制了宽高和点击事件，用于显示和刷新验证码 -->
  <div class="ValidCode disabled-select"
       :style="`width:${width}; height:${height}`"
       @click="refreshCode">
    <!-- 循环渲染每个验证码字符，应用动态样式 -->
    <span v-for="(item, index) in codeList"
          :key="index"
          :style="getStyle(item)">
      {{ item.code }}
    </span>
  </div>
</template>

<script setup>
// 引入 Vue Composition API 函数
import { ref, onMounted } from 'vue';

// 设置组件可以发出的事件
const emit = defineEmits(['input']);

// 定义响应式变量，并设置默认值
const width = ref('100px'); // 宽度
const height = ref('34px'); // 高度
const length = ref(4); // 验证码长度
const codeList = ref([]); // 验证码列表

// 组件挂载时调用生成验证码的函数
onMounted(() => {
  createdCode();
});

// 更新验证码的函数
function refreshCode() {
  createdCode();
}

// 生成验证码的函数
function createdCode() {
  const len = length.value; // 获取验证码的长度
  const newCodeList = []; // 新验证码列表
  const chars = 'ABDEFGHNQRTUVYabcdefhijmnprtyz0123456789'; // 验证码字符集
  const charsLen = chars.length; // 字符集长度

  // 循环生成每个验证码字符
  for (let i = 0; i < len; i++) {
    const rgb = [Math.round(Math.random() * 220), Math.round(Math.random() * 240), Math.round(Math.random() * 200)];
    newCodeList.push({
      code: chars.charAt(Math.floor(Math.random() * charsLen)),
      color: `rgb(${rgb})`,
      fontSize: `1${[Math.floor(Math.random() * 10)]}px`,
      padding: `${[Math.floor(Math.random() * 10)]}px`,
      transform: `rotate(${Math.floor(Math.random() * 90) - Math.floor(Math.random() * 90)}deg)`
    });
  }

  codeList.value = newCodeList; // 将新验证码列表赋值给响应式变量
  emit('input', newCodeList.map(item => item.code).join('')); // 发出事件，传递验证码字符串
}

// 获取验证码字符样式的函数
function getStyle(data) {
  // 返回动态样式字符串
  return `color: ${data.color}; font-size: ${data.fontSize}; padding: ${data.padding}; transform: ${data.transform}`;
}
</script>

<style scoped>
.ValidCode {
  display: flex; /* 使用弹性盒子布局 */
  justify-content: center; /* 横向居中显示验证码字符 */
  align-items: center; /* 纵向居中显示验证码字符 */
  cursor: pointer; /* 鼠标悬停时显示指针形状 */
  user-select: none; /* 阻止文本被选中 */
}
span {
  display: inline-block; /* span元素以内联块形式展示 */
}
</style>